﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Access.PowerTools.AbstractionLayer;
using SMSConsulting.SMSLIB.Utilities;

using acc = Microsoft.Office.Interop.Access;
using System.Globalization;
using System.Data.OleDb;   

namespace Access.PowerTools.Automation.Engine
{
    public partial class AutomationCommunicationBridge
    {
        public bool CompactCurrentDatabase_newVersions()
        {
            try
            {
                // dao.Database dbs = _application.CurrentDb();  


                setThreadCultureInfo();
                CloseCurrentDatabase();

                System.Threading.Thread.Sleep(1000);

                string currentDbFolder = System.IO.Path.GetDirectoryName(_currentDatabaseFullPath);
                string currentDbName = System.IO.Path.GetFileName(_currentDatabaseFullPath);
                string tempDbFullPath = System.IO.Path.Combine(currentDbFolder, "~tempDb.mdb");

                Console.WriteLine("Compacting...");

                _application.CompactRepair(_currentDatabaseFullPath, tempDbFullPath, true);

                string copyDbFullPath = System.IO.Path.Combine(currentDbFolder, "~" + currentDbName);

                Console.WriteLine("Moving...");
                System.IO.File.Move(_currentDatabaseFullPath, copyDbFullPath);
                System.IO.File.Move(tempDbFullPath, _currentDatabaseFullPath);

                Console.WriteLine("Deleting...");
                System.IO.File.Delete(copyDbFullPath);

                _objects = null;
                _database = null;

                OpenCurrentDatabase(_currentDatabaseFullPath);

                return true;
            }
            catch (Exception ex)
            {
                //LOG: 14/02/2010 19:40:18 - CompactCurrentDatabase: You attempted to open a database that is already opened exclusively by user 'Admin' on machine 'HAMBURG'.  Try again when the database is available.
                //LOG: 14/02/2010 19:40:18 - CompactCurrentDatabase:    at Microsoft.Office.Interop.Access.ApplicationClass.CompactRepair(String SourceFile, String DestinationFile, Boolean LogFile)
                //at Access.PowerTools.Automation.Engine.AutomationCommunicationBridge.CompactCurrentDatabase() in E:\MyProjects\Add-In-Express\Access.PowerTools\Code\Access.PowerTools.Automation.Engine\AutomationCommunicationBridge.cs:line 127

                SimpleLogWriter.WriteLogLine("CompactCurrentDatabase: " + ex.Message);
                SimpleLogWriter.WriteLogLine("CompactCurrentDatabase: " + ex.StackTrace);
                return false;
            }
            finally { restoreThreadCultureInfo(); }
        }

        private void initDatabaseOLD()
        {
            _objects = new List<AccessDatabaseObjectInfo>();

            Microsoft.Office.Interop.Access._CurrentProject project = null;
            Microsoft.Office.Interop.Access.AllObjects forms = null;
            Microsoft.Office.Interop.Access.AllObjects reports = null;
            Microsoft.Office.Interop.Access.AllObjects macros = null;
            Microsoft.Office.Interop.Access.AllObjects modules = null;
            try
            {
                project = _application.CurrentProject;
                if (project == null) return;

                // get forms
                forms = project.AllForms;
                getObjects(AccessDataBaseObjectTypeEnumeration.Form, forms);
                // get reports
                reports = project.AllReports;
                getObjects(AccessDataBaseObjectTypeEnumeration.Report, reports);
                // get macros
                macros = project.AllMacros;
                getObjects(AccessDataBaseObjectTypeEnumeration.Macro, macros);
                // get modules
                modules = project.AllModules;
                getObjects(AccessDataBaseObjectTypeEnumeration.Module, modules);

            }
            catch (Exception ex)
            {
                SimpleLogWriter.WriteLogLine("AutomationCommunicationBridge.initDatabase: " +
                    ex.Message);
            }
            finally
            {
                project = null;
                forms = null;
                reports = null;
                macros = null;
                modules = null;
                GC.Collect();
            }

            _database = new AccessDatabase(this);

        }

        private void getObjects(
             AccessDataBaseObjectTypeEnumeration objectType,
             Microsoft.Office.Interop.Access.AllObjects allObjects)
        {
            if (allObjects != null)
            {
                for (int i = 0; i < allObjects.Count; i++)
                {
                    Microsoft.Office.Interop.Access.AccessObject accessObject = allObjects[i];
                    AccessDatabaseObjectInfo objectInfo =
                        new AccessDatabaseObjectInfo(
                            objectType,
                            accessObject.Name);
                    accessObject = null;
                }
            }
        }


        private string connectionString
        {
            get
            {
                return string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}",
                                      _currentDatabaseFullPath);
            }
        }

        public List<AccessDatabaseObjectInfo> GetObjectsInfoOLD(string accessDbFullPath)
        {
            _currentDatabaseFullPath = accessDbFullPath;
            return getAllObjectsInfoOLD();
        }

        private void getTablesAndQueries()
        {
            List<AccessDatabaseObjectInfo> list = getAllObjectsInfoOLD();
            foreach (AccessDatabaseObjectInfo objectInfo in list)
            {
                if (objectInfo.Type == AccessDataBaseObjectTypeEnumeration.Table ||
                    objectInfo.Type == AccessDataBaseObjectTypeEnumeration.Query)
                    _objects.Add(objectInfo);
            }
        }

        private List<AccessDatabaseObjectInfo> getAllObjectsInfoOLD()
        {
            List<AccessDatabaseObjectInfo> list = new List<AccessDatabaseObjectInfo>();

            if (_objects == null) _objects = new List<AccessDatabaseObjectInfo>();

            OleDbCommand cmd = null;
            using (OleDbConnection cnn = new OleDbConnection(connectionString))
            {
                cnn.Open();
                cmd = new OleDbCommand(objectSelectionSQL, cnn);
                OleDbDataReader rdr = null;

                try
                {
                    rdr = cmd.ExecuteReader();
                }
                catch (Exception ex)
                {
                    //- AutomationCommunicationBridge.getAllObjectsInfo: Record(s) cannot be read; no read permission on 'MSysObjects'.
                    string message = "";
                    if (ex.InnerException != null)
                        message = ex.InnerException.Message;
                    if (!string.IsNullOrEmpty(message))
                    {
                        message += System.Environment.NewLine +
                                   "====" +
                                   System.Environment.NewLine;
                    }
                    message += ex.Message;

                    SimpleLogWriter.WriteLogLine("AutomationCommunicationBridge.getAllObjectsInfo: " +
                                    message);
                    throw;
                }

                if (!rdr.Read()) return list;

                while (rdr.Read())
                {
                    int type = rdr.GetInt32(0);
                    string name = rdr.GetString(1);

                    AccessDatabaseObjectInfo objectInfo = new
                     AccessDatabaseObjectInfo(
                      (AccessDataBaseObjectTypeEnumeration)type, name);

                    if (objectInfo.Type == AccessDataBaseObjectTypeEnumeration.Table ||
                        objectInfo.Type == AccessDataBaseObjectTypeEnumeration.Query)
                        _objects.Add(objectInfo);
                }

                rdr.Close();
            }

            return list;
        }


        private string objectSelectionSQL
        {
            get
            {
                return
                     "SELECT " +
                     "  Switch( " +
                     "    [Type]=1,0, " +
                     "    [Type]=5,1, " +
                     "    [Type]=-32768,2, " +
                     "    [Type]=-32764,3, " +
                     "    [Type]=-32766,4, " +
                     "    [Type]=-32761,5) AS acObjectType, " +
                     "  Choose( " +
                     "   [acObjectType]+1,'Table','Query','Form','Report','Macro','Module') AS ObjectTypeName, " +
                     "   MSysObjects.Name as ObjectName " +
                     " FROM MSysObjects " +
                     " WHERE " +
                     "   ((Not (Switch( " +
                     "       [Type]=1,0,[Type]=5,1,[Type]=-32768,2,[Type]=-32764,3,[Type]=-32766,4,[Type]=-32761,5)) Is Null) AND ((MSysObjects.Name) Not Like '~*')) " +
                     " ORDER BY Switch([Type]=1,0,[Type]=5,1,[Type]=-32768,2,[Type]=-32764,3,[Type]=-32766,4,[Type]=-32761,5), MSysObjects.Name;";
            }
        }
    }
}
